package com.touch.jgloo;
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import javax.media.opengl.*;
import javax.imageio.*;
import javax.swing.*;
import com.sun.opengl.util.texture.*;
/**
 * Helper Class that is used in loading Textures
 * @author Homicidal Monkey
 * @version 10.1.9
 * @since r419
 * @see com/touch/Licence
 */
public class JGLTextureLoader 
{
	/**
	* Blank texture used when the texture cannot be found
	* @since r461
	*/
	public static Texture BLANK;
	/**
	* Makes a blank 1x1 pixel image
	* @return A blank image
	* @since r461
	*/
    public static final BufferedImage makeBufferedImage()
    {
        final BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
        final Graphics          g       = img.createGraphics();
        
        g.drawRect(0, 0, 1, 1);
        g.dispose();
        return img;
    }
    /**
     * Loads an image as a Texture
     * @param bImg BufferedImage to load
     * @param mipmap Use mipmap?
     * @return Texture loaded
     * @since r461
     */
     public static final Texture loadIMG(final BufferedImage bImg, final boolean mipmap)
     {
         final Texture text = TextureIO.newTexture(bImg, mipmap);
         text.setTexParameteri(GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
         text.setTexParameteri(GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
         text.setTexParameteri(GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
         text.setTexParameteri(GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
         
         return text;
     }
     /**
      * Loads an image from an Input stream using specified extension
      * @param iFile InputStream of the image
      * @param mipmap use mipmaps
      * @param ext String extension
      * @since r461
      */
     public static final Texture loadIMG(final InputStream iFile, final boolean mipmap, final String ext)              
     {
         final Texture text;
         final BufferedImage bImg;

         if(iFile == null)
        	 bImg = makeBufferedImage();                 
         else
        	 bImg = processBufferedImage(makeBufferedImage(makeImage(iFile)));                                                       
         text = loadIMG(bImg, mipmap);
         return text;               
     }       
     /**
      * Loads an Image as a Texture, but does not process it. Use this if there are problems with alpha channels.      * 
      * @param iFile
      * @param mipmap
      * @param ext
      * @return Texture loaded
      * @since r461
      */
     public static final Texture loadUnprocessedIMG(InputStream iFile, boolean mipmap, String ext)
     {
         final Texture text;
         try
         {
             text = TextureIO.newTexture(iFile, mipmap, ext);
             return text;
         }
         catch(final Exception e)
         {
        	 e.printStackTrace();
        	 return BLANK;
         }
     }
     /**
      * Creates a BufferedImage from an Image
      * @param image Image file
      * @return BufferedImage 
      * @sice r461
      */
     public static final BufferedImage generateBufferedImage(final Image image)
     {               
	     try 
	     {
	         final BufferedImage bimage;
	         final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();   
	         final int transparency = Transparency.TRANSLUCENT;               
	         final GraphicsDevice gs = ge.getDefaultScreenDevice();
	         final GraphicsConfiguration gc = gs.getDefaultConfiguration();
	         
	         bimage = gc.createCompatibleImage(
	             image.getWidth(null), image.getHeight(null), transparency);
	         return bimage;
	     } 
	     catch (final Exception e)
	     {
	    	 e.printStackTrace();
	    	 return null;
	     }        
     }
 /**
  * This method returns a buffered image with the contents of an image
  * @param image
  * @return
  * @since r461
  */
 public static final BufferedImage makeBufferedImage(Image image)
 {          
     // This code ensures that all the pixels in the image are loaded
     image = new ImageIcon(image).getImage();
 
     // Determine if the image has transparent pixels; for this method's
     // implementation, see e661 Determining If an Image Has Transparent Pixels
     final boolean hasAlpha = hasAlpha(image);
     if (image instanceof BufferedImage)
     {
             if(hasAlpha)
                     return (BufferedImage)image;
     }
     
     BufferedImage bimage = generateBufferedImage(image);
 
     if (bimage == null) {
         // Create a buffered image using the default color model
         int type = BufferedImage.TYPE_INT_RGB;
         if (hasAlpha)
             type = BufferedImage.TYPE_INT_ARGB;
         bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
     }
 
     // Copy image to buffered image
     final Graphics g = bimage.createGraphics();
 
     // Paint the image onto the buffered image
     g.drawImage(image, 0, 0, null);
     g.dispose();
 
     return bimage;
 }
 /**
  * @since r461
  * @param image
  * @return
  */
 public static final boolean hasAlpha(final Image image)
 {      
     if (image instanceof BufferedImage) 
     {
         final BufferedImage bimage = (BufferedImage)image;
         return bimage.getColorModel().hasAlpha();
     }
     
     final PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
     try
     {
         pg.grabPixels();
     }
     catch(final Exception e)
     {
         return false;
     }
 
     // Get the image's color model
     final ColorModel cm = pg.getColorModel();
     return cm.hasAlpha();
 }
 /**
  * 
  * @param iFile
  * @return
  * @since r461
  */
 public static final Image makeImage(final InputStream iFile)
 {                   
     final Image image;              
     try
     {
         image = ImageIO.read(iFile);
     }
     catch(Exception e)
     {
    	 return null;
     }
     return image;
 }
 /**
  * 
  * @param bImage
  * @return
  * @since r461
  */
 public static final BufferedImage processBufferedImage(BufferedImage bImage)
 {
     final int x, y; 
     int p, filterColor;
     
     x = bImage.getWidth();
     y = bImage.getHeight();
     Color color, mColor;
     filterColor = bImage.getRGB(0,0);
     for(int x1 = 0; x1 < x; x1++)
     {
         for(int y1 = 0; y1 < y; y1++)
         {
             p = bImage.getRGB(x1, y1);                      
             color = new Color(p);   
             if(p == filterColor)
                 mColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), 0);                       
             else
                 mColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());                        
             bImage.setRGB(x1, y1, mColor.getRGB());         
         }
     }       
     return bImage;
 }

}
